package com.new1cloud.file.upload.client.bootstrap;

import com.new1cloud.file.tools.FileSlicerTool;
import com.new1cloud.file.upload.client.entry.ChunkFile;
import io.netty.channel.ChannelHandlerContext;
import lombok.Cleanup;
import lombok.SneakyThrows;

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 文件分片（基于MappedByteBuffer）
 */
public class FileSlicerOnMappedByteBuffer implements IFileSlicer {

    @Override
    @SneakyThrows
    public ChunkFile gotChunkFileBytes(ChannelHandlerContext ctx, String sourceFilePath, Long position, Long chunkSize, ChunkFile chunkFile) {
        @Cleanup RandomAccessFile file = new RandomAccessFile(sourceFilePath, "r");
        @Cleanup FileChannel channel = file.getChannel();
        final long fileSize = channel.size();
        if(position >= fileSize) {
            return chunkFile;
        }

        // 计算当前切片的结束位置，防止超过文件末尾
        long limit = Math.min(position + chunkSize, fileSize);
        long readSize = limit - position;
        // 映射当前切片（关闭 `FileChannel` 和 `RandomAccessFile`，它们会自动关闭关联的 `MappedByteBuffer`）
        MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, position, readSize);
        // 创建一个字节数组来存储切片数据
        byte[] sliceData = new byte[(int) (readSize)];
        // 将映射的缓冲区数据复制到字节数组中
        buffer.get(sliceData);
        chunkFile.setChunkData(null);
        return chunkFile;
    }
}
